package com.gxgeek.rule;

import com.gxgeek.CoreConstants;
import com.gxgeek.dto.NodeResult;
import com.gxgeek.dto.Rule;
import com.gxgeek.dto.RuleCondition;
import com.gxgeek.dto.biz.RiskCoreDTO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;

/**
 * @author gaoxing
 * @create 2018-05-23 下午2:16
 */
@Service
public class RiskRuleExecService {
    @Autowired
    GroovyService groovyService;

    /**
     *
     * @param ruleList 规则列表
     * @param riskCoreDTO
     * @param data  //规则所需要的数据
     * @return
     */
    public NodeResult execNode(List<Rule> ruleList, RiskCoreDTO riskCoreDTO, Map<String, Object> data){
        NodeResult nodeResult =new NodeResult();

        List<Rule> passRule = ruleList.stream().filter(s -> execRule(s, data)).collect(toList());
        //todo 将用户 经历的 规则条件入库

        int ruleScorecount = passRule.stream().mapToInt(Rule::getRuleScore).sum();
        List<String> ruleCodeList = passRule.stream()
                .map(Rule::getRuleCode).collect(toList());
        List<String>  notifyPolicyList = passRule.stream()
                .filter(s-> StringUtils.isNotBlank(s.getNotifyPolicy()))
                .map(Rule::getNotifyPolicy).collect(toList());
        nodeResult.setNodeScore(ruleScorecount);
        nodeResult.setTriggerRules(ruleCodeList);
        nodeResult.setNotifyPolicy(notifyPolicyList);

        return nodeResult;
    }

    private boolean execRule(Rule rule, Map<String, Object> data) {
        Map<Long,Boolean> allResults=new HashMap<>();
        for (RuleCondition condition : rule.getConditions()) {
            //todo 作用未知
            data.putAll(condition.getCondParams());

            boolean result = execCondition(condition, data);
            allResults.put(condition.getId(), result);

        }
        return groovyService.caculateExpress(rule.getCondExpress(), allResults);
    }

    private boolean execCondition(RuleCondition condition, Map<String, Object> data) {
       return (boolean) condition.getGroovy().invokeMethod(CoreConstants.Groovy.GROOVY_METHOD_NAME, data);
    }

}
